[Thunor: Note that the book simply includes a Sinclair printer printout showing an address, a byte and a character, and so I have decided to concatenate the listing from chapter 9.]
HEXLD3 - NEW ROM
Program Organisation
The HEXLD3 machine code is stored independently
within a line 1 REM statement of 255 bytes in size.
The user writes his/her machine code programs to
somewhere else and uses RUN 400 to copy it in and
subsequently out of an array to save it.
DecimalHexRoutine/Variable
16514 4082 HPRINT
16531 4093 BEGIN
16533 4095 ADDRESS
16535 4097 ADD2
16537 4099 LIMIT
16539 409B HLIST
16589 40CD WRITE
16635 40FB ARRAY
16651 410B STORE
16669 411D RETRIEVE
16687 412F INSERT
16732 415C DELETE
Program Listing
4082: F5 HPRINT PUSH AF
4083: E6F0 AND F0
4085: 1F RRA
4086: 1F RRA
4087: 1F RRA
4088: 1F RRA
4089: C61C ADD A,1C
408B: D7 RST 10
408C: F1 POP AF
408D: E60F AND 0F
408F: C61C ADD A,1C
4091: D7 RST 10
4092: C9 RET
17 bytes.
4093: 0000 BEGIN DEFB 00 00
4095: 0000 ADDRESS DEFB 00 00
4097: 0000 ADD2 DEFB 00 00
4099: 0000 LIMIT DEFB 00 00
8 bytes.
409B: 2A9940 HLIST LD HL,(LIMIT)
409E: 229740 LD (ADD2),HL
40A1: 54 LD D,H
40A2: 5D LD E,L
40A3: 2A9540 LD HL,(ADDRESS)
40A6: A7 NXTAD AND A
40A7: ED52 SBC HL,DE
40A9: 19 ADD HL,DE
40AA: 301F JR NC,DONE
40AC: 7C LD A,H
40AD: CD8240 CALL HPRINT
40B0: 7D LD A,L
40B1: CD8240 CALL HPRINT
40B4: AF XOR A
40B5: D7 RST 10
40B6: 7E LD A,(HL)
40B7: CD8240 CALL HPRINT
40BA: CB76 BIT 6,(HL)
40BC: 2004 JR NZ,NOPRINT
40BE: AF XOR A
40BF: D7 RST 10
40C0: 7E LD A,(HL)
40C1: D7 RST 10
40C2: 3E76 NOPRINT LD A,76
40C4: D7 RST 10
40C5: 23 INC HL
40C6: 229540 LD (ADDRESS),HL
40C9: 18DB JR NXTAD
40CB: CF DONE RST 08
40CC: 00 DEFB 00
50 bytes.
40CD: 2A1040 WRITE LD HL,(VARS)
40D0: 23 INC HL
40D1: 46 LD B, (HL)
40D2: 23 INC HL
40D3: CB28 SRA B
40D5: 28F4 JR Z,DONE
40D7: ED5B9540 LD DE,(ADDRESS)
40DB: 23 NEXTBYTE INC HL
40DC: 7E LD A,(HL)
40DD: 87 ADD A,A
40DE: 87 ADD A,A
40DF: 87 ADD A,A
40E0: 87 ADD A,A
40E1: 23 INC HL
40E2: 86 ADD A,(HL)
40E3: C624 ADD A,24
40E5: 12 LD (DE),A
40E6: 13 INC DE
40E7: ED539540 LD (ADDRESS),DE
40EB: E5 PUSH HL
40EC: 2A9940 LD HL,(LIMIT)
40EF: ED52 SBC HL,DE
40F1: E1 POP HL
40F2: 3004 JR NC,CHECK
40F4: ED539940 LD (LIMIT),DE
40F8: 10E1 CHECK DJNZ NEXTBYTE
40FA: C9 RET
46 bytes.
40FB: 2A9940 ARRAY LD HL,(LIMIT)
40FE: ED5B9340 LD DE,(BEGIN)
4102: A7 AND A
4103: ED52 SBC HL,DE
4105: 229740 LD (ADD2),HL
4108: 44 LD B,H
4109: 4D LD C,L
410A: C9 RET
16 bytes.
410B: 2A1040 STORE LD HL,(VARS)
410E: 110600 LD DE,0006
4111: 19 ADD HL,DE
4112: EB EX DE,HL
4113: 2A9340 LD HL,(BEGIN)
4116: ED4B9740 LD BC,(ADD2)
411A: EDB0 LDIR
411C: C9 RET
18 bytes.
411D: 2A1040 RETRIEVE LD HL,(VARS)
4120: 110600 LD DE,0006
4123: 19 ADD HL,DE
4124: ED5B9340 LD DE,(BEGIN)
4128: ED4B9740 LD BC,(ADD2)
412C: EDB0 LDIR
412E: C9 RET
18 bytes.
412F: 2A1040 INSERT LD HL,(VARS)
4132: 23 INC HL
4133: 4E LD C,(HL)
4134: 23 INC HL
4135: 46 LD B,(HL)
4136: CB28 COPYUP SRA B
4138: CB19 RR C
413A: 2002 JR NZ,NOTEMPTY
413C: CF RST 08
413D: 08 DEFB 08
413E: C5 NOTEMPTY PUSH BC
413F: 2A9940 LD HL,(LIMIT)
4142: ED5B9540 LD DE,(ADDRESS)
4146: A7 AND A
4147: ED52 SBC HL,DE
4149: 23 INC HL
414A: 44 LD B,H
414B: 4D LD C,L
414C: E1 POP HL
414D: ED5B9940 LD DE,(LIMIT)
4151: 19 ADD HL,DE
4152: 229940 LD (LIMIT),HL
4155: EB EX DE,HL
4156: EDB8 LDDR
4158: CDCD40 CALL WRITE
415B: C9 RET
45 bytes.
415C: 2A9940 DELETE LD HL,(LIMIT)
415F: ED5B9740 LD DE,(ADD2)
4163: D5 PUSH DE
4164: A7 AND A
4165: ED52 SBC HL,DE
4167: 44 LD B,H
4168: 4D LD C,L
4169: E1 POP HL
416A: 23 INC HL
416B: ED5B9540 LD DE,(ADDRESS)
416F: EDB0 LDIR
4171: 1B DEC DE
4172: ED539940 LD (LIMIT),DE
4176: CF RST 08
4177: 08 DEFB 08
28 bytes.
Total 246 bytes.
The BASIC Part
1 REM 255-arbitrary-characters-to-store-HEXLD3
10 PRINT "LIST"
20 GOSUB 600
30 RAND USR 16539
100 PRINT "WRITE"
110 GOSUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RAND USR 16589
150 GOTO 120
200 PRINT "INSERT"
210 GOSUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RAND USR 16687
250 GOTO 220
300 PRINT "DELETE"
305 PRINT "START "; [Thunor: I added this; it's optional]
310 GOSUB 600
320 LET A=16535
325 PRINT "END "; [Thunor: I added this; it's optional]
330 GOSUB 610
340 RAND USR 16732
400 DIM O$(USR 16635)
410 RAND USR 16651
420 SAVE "HEXLD3"
500 RAND USR 16669
510 CLEAR
520 STOP
600 LET A=16533
610 PRINT "ADDRESS ";
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE A$+CODE A$(2)-476
650 POKE A,16*CODE A$(3)+CODE A$(4)-476
660 CLEAR
670 RETURN
Operating Instructions
Don't forget that if you intend to write in high memory then
you need to set RAMTOP and execute NEW before loading HEXLD3.
To initialise HEXLD3 for a new program:
1. Type RUN 100 and enter the address of the variable BEGIN (4093h).
2. Input the start address of the program you are about to write in
reverse order i.e. 4C00 would be "004C".
3. Type newline on its own to quit writing.
4. Type RUN 100 to begin inputting a program.
5. Type RUN 400 to save your machine code program.
Thereafter:
RUN To List your machine code program.
Use CONT to continue listing up until LIMIT.
RUN 100 To Write new machine code.
Type newline on its own to quit.
RUN 200 To Insert new machine code.
Type newline on its own to quit.
RUN 300 To Delete previous machine code.
Enter the start and end addresses to delete.
RUN 400 To Save your machine code program.
Your machine code is automatically restored on load.
[Thunor: Adapted from the NEW ROM version by myself as the author didn't supply a complete OLD ROM version. This version is Draughts ready, meaning that the machine code relocation that NEW ROM users will be asked to do in chapter 11 is unnecessary (the machine code is already located where Draughts requires it to be), the modification to BASIC line 500 to execute RETRIEVE from inside the O array has already been applied (BASIC line 504), and the issue with RETRIEVE not referencing BEGIN and ADD2 from within the O array has been fixed in BASIC lines 500 to 503.
Program Organisation
The HEXLD3 machine code is initially written to
4A1A and then stored within an array on save. When
HEXLD3 is reloaded it is copied from the array
back to its original memory location by executing
GO TO 500. Note that the value stored in BEGIN is
4A00 and so there are 26 unused bytes before 4A1A.
The user's own code appends the HEXLD3 machine code.
So when the user executes RUN 400 to copy his work
to an array for saving, he also saves HEXLD3.
Subsequently restoring the code after reloading the
program with GO TO 500 will restore HEXLD3 to 4A1A.
DecimalHexRoutine/Variable
18970 4A1A APRINT
18983 4A27 HPRINT
19004 4A3C BEGIN
19006 4A3E ADDRESS
19008 4A40 ADD2
19010 4A42 LIMIT
19012 4A44 HLIST
19072 4A80 WRITE
19125 4AB5 ARRAY
19143 4AC7 STORE
19161 4AD9 RETRIEVE
19179 4AEB INSERT
19231 4B1F DELETE
Program Listing
4A1A: E5 APRINT PUSH HL
4A1B: D9 EXX
4A1C: F5 PUSH AF
4A1D: CDE006 CALL PRPOS
4A20: F1 POP AF
4A21: CD2007 CALL PRINT
4A24: D9 EXX
4A25: E1 POP HL
4A26: C9 RET
13 bytes.
4A27: F5 HPRINT PUSH AF
4A28: E6F0 AND F0
4A2A: 1F RRA
4A2B: 1F RRA
4A2C: 1F RRA
4A2D: 1F RRA
4A2E: C61C ADD A,1C
4A30: CD1A4A CALL APRINT
4A33: F1 POP AF
4A34: E60F AND 0F
4A36: C61C ADD A,1C
4A38: CD1A4A CALL APRINT
4A3B: C9 RET
21 bytes.
4A3C: 0000 BEGIN DEFB 00 00
4A3E: 0000 ADDRESS DEFB 00 00
4A40: 0000 ADD2 DEFB 00 00
4A42: 0000 LIMIT DEFB 00 00
8 bytes.
4A44: 2A424A HLIST LD HL,(LIMIT)
4A47: 22404A LD (ADD2),HL
4A4A: 54 LD D,H
4A4B: 5D LD E,L
4A4C: 2A3E4A LD HL,(ADDRESS)
4A4F: 0616 LD B,16
4A51: A7 NXTAD AND A
4A52: ED52 SBC HL,DE
4A54: 19 ADD HL,DE
4A55: 3027 JR NC,DONE
4A57: 7C LD A,H
4A58: CD274A CALL HPRINT
4A5B: 7D LD A,L
4A5C: CD274A CALL HPRINT
4A5F: AF XOR A
4A60: CD1A4A CALL APRINT
4A63: 7E LD A,(HL)
4A64: CD274A CALL HPRINT
4A67: CB76 BIT 6,(HL)
4A69: 2008 JR NZ,NOPRINT
4A6B: AF XOR A
4A6C: CD1A4A CALL APRINT
4A6F: 7E LD A,(HL)
4A70: CD1A4A CALL APRINT
4A73: 3E76 NOPRINT LD A,76
4A75: CD1A4A CALL APRINT
4A78: 23 INC HL
4A79: 223E4A LD (ADDRESS),HL
4A7C: 10D3 DJNZ NXTAD
4A7E: CF DONE RST 08
4A7F: 00 DEFB 00
60 bytes.
4A80: 2A0840 WRITE LD HL,(VARS)
4A83: E5 PUSH HL
4A84: 06FF LD B,FF
4A86: 23 ANOTHER INC HL
4A87: 7E LD A,(HL)
4A88: 04 INC B
4A89: 3D DEC A
4A8A: 20FA JR NZ,ANOTHER
4A8C: E1 POP HL
4A8D: CB28 SRA B
4A8F: 28ED JR Z,DONE
4A91: ED5B3E4A LD DE,(ADDRESS)
4A95: 23 NEXTBYTE INC HL
4A96: 7E LD A,(HL)
4A97: 87 ADD A,A
4A98: 87 ADD A,A
4A99: 87 ADD A,A
4A9A: 87 ADD A,A
4A9B: 23 INC HL
4A9C: 86 ADD A,(HL)
4A9D: C624 ADD A,24
4A9F: 12 LD (DE),A
4AA0: 13 INC DE
4AA1: ED533E4A LD (ADDRESS),DE
4AA5: E5 PUSH HL
4AA6: 2A424A LD HL,(LIMIT)
4AA9: ED52 SBC HL,DE
4AAB: E1 POP HL
4AAC: 3004 JR NC,CHECK
4AAE: ED53424A LD (LIMIT),DE
4AB2: 10E1 CHECK DJNZ NEXTBYTE
4AB4: C9 RET
53 bytes.
4AB5: 2A424A ARRAY LD HL,(LIMIT)
4AB8: ED5B3C4A LD DE,(BEGIN)
4ABC: A7 AND A
4ABD: ED52 SBC HL,DE
4ABF: 22404A LD (ADD2),HL
4AC2: CB2C SRA H
4AC4: CB1D RR L
4AC6: C9 RET
18 bytes.
4AC7: 2A0840 STORE LD HL,(VARS)
4ACA: 110600 LD DE,0006
4ACD: 19 ADD HL,DE
4ACE: EB EX DE,HL
4ACF: 2A3C4A LD HL,(BEGIN)
4AD2: ED4B404A LD BC,(ADD2)
4AD6: EDB0 LDIR
4AD8: C9 RET
18 bytes.
4AD9: 2A0840 RETRIEVE LD HL,(VARS)
4ADC: 110600 LD DE,0006
4ADF: 19 ADD HL,DE
4AE0: ED5B3C4A LD DE,(BEGIN)
4AE4: ED4B404A LD BC,(ADD2)
4AE8: EDB0 LDIR
4AEA: C9 RET
18 bytes.
4AEB: 2A0840 INSERT LD HL,(VARS)
4AEE: E5 PUSH HL
4AEF: 01FFFF LD BC,FFFF
4AF2: 23 MORE INC HL
4AF3: 7E LD A,(HL)
4AF4: 03 INC BC
4AF5: 3D DEC A
4AF6: 20FA JR NZ,MORE
4AF8: E1 POP HL
4AF9: CB28 COPYUP SRA B
4AFB: CB19 RR C
4AFD: 2002 JR NZ,NOTEMPTY
4AFF: CF RST 08
4B00: 08 DEFB 08
4B01: C5 NOTEMPTY PUSH BC
4B02: 2A424A LD HL,(LIMIT)
4B05: ED5B3E4A LD DE,(ADDRESS)
4B09: A7 AND A
4B0A: ED52 SBC HL,DE
4B0C: 23 INC HL
4B0D: 44 LD B,H
4B0E: 4D LD C,L
4B0F: E1 POP HL
4B10: ED5B424A LD DE,(LIMIT)
4B14: 19 ADD HL,DE
4B15: 22424A LD (LIMIT),HL
4B18: EB EX DE,HL
4B19: EDB8 LDDR
4B1B: CD804A CALL WRITE
4B1E: C9 RET
52 bytes.
4B1F: 2A424A DELETE LD HL,(LIMIT)
4B22: ED5B404A LD DE,(ADD2)
4B26: D5 PUSH DE
4B27: A7 AND A
4B28: ED52 SBC HL,DE
4B2A: 44 LD B,H
4B2B: 4D LD C,L
4B2C: E1 POP HL
4B2D: 23 INC HL
4B2E: ED5B3E4A LD DE,(ADDRESS)
4B32: EDB0 LDIR
4B34: 1B DEC DE
4B35: ED53424A LD (LIMIT),DE
4B39: CF RST 08
4B3A: 08 DEFB 08
28 bytes.
Total 289 bytes.
The BASIC Part
10 PRINT "LIST"
20 GO SUB 600
30 RANDOMISE USR(19012)
100 PRINT "WRITE"
110 GO SUB 600
120 INPUT A$
130 PRINT A$;" ";
140 RANDOMISE USR(19072)
150 GO TO 120
200 PRINT "INSERT"
210 GO SUB 600
220 INPUT A$
230 PRINT A$;" ";
240 RANDOMISE USR(19179)
250 GO TO 220
300 PRINT "DELETE"
305 PRINT "START ";
310 GO SUB 600
320 LET A=19008
325 PRINT "END ";
330 GO SUB 610
340 RANDOMISE USR(19231)
400 DIM O(USR(19125))
410 RANDOMISE USR(19143)
420 SAVE
500 POKE 19004,PEEK(PEEK(16392)+PEEK(16393)*256+6+26+34)
501 POKE 19005,PEEK(PEEK(16392)+PEEK(16393)*256+6+26+35)
502 POKE 19008,PEEK(PEEK(16392)+PEEK(16393)*256+6+26+38)
503 POKE 19009,PEEK(PEEK(16392)+PEEK(16393)*256+6+26+39)
504 RANDOMISE USR(PEEK(16392)+PEEK(16393)*256+6+26+191)
520 STOP
600 LET A=19006
610 PRINT "ADDRESS ";
620 INPUT A$
630 PRINT A$
640 POKE A+1,16*CODE(A$)+CODE(TL$(A$))-476
650 POKE A,16*CODE(TL$(TL$(A$)))+CODE(TL$(TL$(TL$(A$))))-476
660 CLEAR
670 RETURN
Operating Instructions
1. Type GO TO 500 to restore HEXLD3's machine code
and your machine code to its correct memory location.
2. Type RUN 100 to begin inputting a program.
3. Type newline on its own to quit writing.
4. Type RUN 400 to save your machine code program.
Thereafter:
RUN To List your machine code program.
Use CONT to continue listing up until LIMIT.
RUN 100 To Write new machine code.
Type newline on its own to quit.
RUN 200 To Insert new machine code.
Type newline on its own to quit.
RUN 300 To Delete previous machine code.
Enter the start and end addresses to delete.
RUN 400 To Save your machine code program.
GO TO 500 To Restore the machine code after loading.